﻿import { Router } from "express";
import crypto from "crypto";
import jwt from 'jsonwebtoken'
import bcrypt from 'bcrypt';

const router = Router();

// 环境变量密钥
const AUTH_SECRET = process.env.AUTH_SECRET || 'your-secret-key' // 生产中从.env加载

// 内存用户数据库：实际项目中应使用真实数据库
const userDb = new Map<string, {
  id: string;
  email: string;
  username: string;
  password: string;
  role: string;
  created_at: string;
  has_face: boolean;
}>();

// 存储 refresh token 的数据库
const refreshTokenDb = new Map<string, {
  token: string;
  userId: string;
  expiresAt: Date;
}>();

// 工具函数：生成 access token (JWT, 24h)
function generateAccessToken(userId: string, role: string): string {
  return jwt.sign(
    { userId, role },
    AUTH_SECRET,
    { expiresIn: '24h' }
  )
}

// 工具函数：生成 refresh token (JWT, 30d)
function generateRefreshToken(userId: string): string {
  const token = jwt.sign(
    { userId },
    AUTH_SECRET,
    { expiresIn: '30d' }
  )
  const decoded = jwt.decode(token) as { exp: number }
  const expiresAt = new Date(decoded.exp * 1000)
  refreshTokenDb.set(token, { token, userId, expiresAt })
  return token
}

// 工具函数：验证 refresh token (JWT验证 + DB检查)
function validateRefreshToken(token: string): { valid: boolean, userId?: string } {
  try {
    const decoded = jwt.verify(token, AUTH_SECRET) as { userId: string }
    const tokenData = refreshTokenDb.get(token)
    if (!tokenData || tokenData.userId !== decoded.userId) {
      return { valid: false }
    }
    if (tokenData.expiresAt < new Date()) {
      refreshTokenDb.delete(token)
      return { valid: false }
    }
    return { valid: true, userId: decoded.userId }
  } catch {
    return { valid: false }
  }
}

// 工具函数：密码哈希 - 使用bcrypt
async function hashPassword(password: string): Promise<string> {
  const saltRounds = 12; // 安全的盐值轮数
  return await bcrypt.hash(password, saltRounds);
}

// 工具函数：验证密码 - 使用bcrypt
async function verifyPassword(password: string, hash: string): Promise<boolean> {
  return await bcrypt.compare(password, hash);
}

// 向后兼容的同步哈希函数（用于迁移旧密码）
function legacyHashPassword(password: string): string {
  return crypto.createHash('sha256').update(password).digest('hex');
}

// 检查是否为旧的SHA256哈希
function isLegacyHash(hash: string): boolean {
  // bcrypt哈希总是以$2开头，SHA256是64字符的十六进制
  return hash.length === 64 && /^[a-f0-9]{64}$/.test(hash);
}

// 解码前端加密的密码
function decodeFrontendPassword(encodedPassword: string): string {
  try {
    const [encoded] = encodedPassword.split('.');
    return Buffer.from(encoded, 'base64').toString('utf-8');
  } catch (error) {
    throw new Error('密码解码失败');
  }
}

// 初始化真实用户账号
const initDefaultUsers = async () => {
  try {
    // 清空现有用户数据，强制重新初始化
    userDb.clear();
    console.log('[系统初始化] 清空现有用户数据，开始重新初始化');
    
    // 超级管理员账号
    const superAdminId = 'u001';
    const superAdminUser = {
      id: superAdminId,
      email: 'jiangjiankai@hospital.com',
      username: 'jiangjiankai',
      password: await hashPassword('jjk123456'),
      role: 'admin',
      created_at: new Date().toISOString(),
      has_face: false
    };
    userDb.set(superAdminId, superAdminUser);

    // 院长账号
    const deanId = 'u002';
    const deanUser = {
      id: deanId,
      email: 'guomengzhe@hospital.com',
      username: 'guomengzhe',
      password: await hashPassword('gmz123456'),
      role: 'manager',
      created_at: new Date().toISOString(),
      has_face: false
    };
    userDb.set(deanId, deanUser);

    // 主任账号
    const directorId = 'u003';
    const directorUser = {
      id: directorId,
      email: 'zhangyiwe@hospital.com',
      username: 'zhangyiwe',
      password: await hashPassword('zyw123456'),
      role: 'manager',
      created_at: new Date().toISOString(),
      has_face: false
    };
    userDb.set(directorId, directorUser);

    // 医生账号
    const doctorId = 'u004';
    const doctorUser = {
      id: doctorId,
      email: 'yaoyuan@hospital.com',
      username: 'yaoyuan',
      password: await hashPassword('yy123456'),
      role: 'user',
      created_at: new Date().toISOString(),
      has_face: false
    };
    userDb.set(doctorId, doctorUser);

    // 护士账号
    const nurseId = 'u005';
    const nurseUser = {
      id: nurseId,
      email: 'limengran@hospital.com',
      username: 'limengran',
      password: await hashPassword('lmr123456'),
      role: 'guide',
      created_at: new Date().toISOString(),
      has_face: false
    };
    userDb.set(nurseId, nurseUser);

    console.log('[系统初始化] 真实用户账号已创建:');
    console.log('  超级管理员: jiangjiankai / jjk123456 (邮箱: jiangjiankai@hospital.com)');
    console.log('  院长: guomengzhe / gmz123456 (邮箱: guomengzhe@hospital.com)');
    console.log('  主任: zhangyiwe / zyw123456 (邮箱: zhangyiwe@hospital.com)');
    console.log('  医生: yaoyuan / yy123456 (邮箱: yaoyuan@hospital.com)');
    console.log('  护士: limengran / lmr123456 (邮箱: limengran@hospital.com)');
    console.log(`[系统初始化] 用户数据库大小: ${userDb.size}`);
  } catch (error) {
    console.error('[系统初始化] 创建默认用户失败:', error);
  }
};

// 初始化默认用户
(async () => {
  try {
    await initDefaultUsers();
    console.log('[系统启动] 用户初始化完成');
  } catch (error) {
    console.error('[系统启动] 用户初始化失败:', error);
  }
})();

// 从人脸库同步用户状态的函数
const syncUserFaceStatus = () => {
  try {
    const fs = require('fs');
    const path = require('path');
    const faceDbPath = path.join(process.cwd(), "face_data.json");
    
    if (fs.existsSync(faceDbPath)) {
      const faceData = JSON.parse(fs.readFileSync(faceDbPath, 'utf-8'));
      
      // 重置所有用户的人脸状态
      for (const [userId, user] of userDb.entries()) {
        user.has_face = false;
        userDb.set(userId, user);
      }
      
      // 根据人脸库设置状态
      let syncCount = 0;
      for (const [personId] of Object.entries(faceData)) {
        for (const [userId, user] of userDb.entries()) {
          if (user.username === personId || user.id === personId || userId === personId) {
            user.has_face = true;
            userDb.set(userId, user);
            syncCount++;
            console.log(`[启动同步] 用户 ${user.username} 人脸状态已同步`);
            break;
          }
        }
      }
      
      console.log(`[启动同步] 完成，同步了 ${syncCount} 个用户的人脸状态`);
    } else {
      console.log('[启动同步] 人脸数据文件不存在，跳过同步');
    }
  } catch (error) {
    console.error('[启动同步] 同步用户人脸状态失败:', error);
  }
};

// 启动时同步用户人脸状态（延迟3秒确保用户初始化完成）
setTimeout(syncUserFaceStatus, 3000);

// 用户注册
router.post("/register", async (req, res) => {
  try {
    const { phone, email, username, password, role } = req.body;

    // 参数验证
    if (!email || !username || !password || !role) {
      return res.status(400).json({ 
        success: false, 
        message: "邮箱、用户名、密码和角色都是必填项" 
      });
    }

    // 角色验证
    if (!['user', 'admin'].includes(role)) {
      return res.status(400).json({ 
        success: false, 
        message: "角色只能是 user 或 admin" 
      });
    }

    // 邮箱格式验证
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(email)) {
      return res.status(400).json({ 
        success: false, 
        message: "请输入有效的邮箱地址" 
      });
    }

    // 用户名格式验证
    if (username.length < 3 || username.length > 20) {
      return res.status(400).json({ 
        success: false, 
        message: "用户名长度应在3-20个字符之间" 
      });
    }

    // 检查邮箱是否已注册
    for (const user of userDb.values()) {
      if (user.email === email) {
        return res.status(400).json({ 
          success: false, 
          message: "该邮箱已注册，请直接登录" 
        });
      }
    }

    // 检查用户名是否已存在
    for (const user of userDb.values()) {
      if (user.username === username) {
        return res.status(400).json({ 
          success: false, 
          message: "用户名已存在，请更换其他用户名" 
        });
      }
    }

    // 创建新用户
    const userId = `user_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;
    const hashedPassword = await hashPassword(password);
    
    const newUser = {
      id: userId,
      email,
      username,
      password: hashedPassword,
      role: role, // 使用用户选择的角色
      created_at: new Date().toISOString(),
      has_face: false
    };

    userDb.set(userId, newUser);

    console.log(`[用户注册] 新用户: ${username} (${email}) - 角色: ${role}`);
    console.log(`[用户注册] 当前用户数: ${userDb.size}`);

    return res.json({
      success: true,
      message: "注册成功",
      username: username,
      role: role
    });

  } catch (error: any) {
    console.error("注册错误:", error);
    return res.status(500).json({ 
      success: false, 
      message: "服务器内部错误" 
    });
  }
});

// 用户登录 - 返回JWT token
router.post("/login", async (req, res) => {
  try {
    const { username, password } = req.body;
    
    console.log(`[登录调试] 尝试登录用户: ${username}`);
    console.log(`[登录调试] 当前用户数据库大小: ${userDb.size}`);
    console.log(`[登录调试] 数据库中的用户:`, Array.from(userDb.values()).map(u => u.username));
    
    if (!username || !password) {
      return res.status(400).json({ 
        success: false, 
        message: "用户名和密码都是必填项" 
      });
    }

    // 查找用户 - 只支持用户名登录
    let foundUser = null;
    for (const user of userDb.values()) {
      if (user.username === username) {
        foundUser = user;
        break;
      }
    }

    if (!foundUser) {
      return res.status(400).json({ 
        success: false, 
        message: "用户名或密码错误" 
      });
    }

    // 验证密码 - 支持新的bcrypt和旧的SHA256
    let passwordValid = false;
    
    if (isLegacyHash(foundUser.password)) {
      // 旧的SHA256哈希，使用同步验证
      passwordValid = legacyHashPassword(password) === foundUser.password;
      
      // 如果验证成功，升级到bcrypt哈希
      if (passwordValid) {
        console.log(`[密码升级] 为用户 ${foundUser.username} 升级密码哈希到bcrypt`);
        foundUser.password = await hashPassword(password);
        userDb.set(foundUser.id, foundUser);
      }
    } else {
      // 新的bcrypt哈希，使用异步验证
      passwordValid = await verifyPassword(password, foundUser.password);
    }
    
    if (!passwordValid) {
      return res.status(400).json({ 
        success: false, 
        message: "用户名或密码错误" 
      });
    }

    console.log(`[用户登录] 用户: ${foundUser.username} (${foundUser.email}) - 角色: ${foundUser.role}`);

    // 生成JWT双 token
    const accessToken = generateAccessToken(foundUser.id, foundUser.role)
    const refreshToken = generateRefreshToken(foundUser.id)

    return res.json({
      success: true,
      access_token: accessToken, // 兼容前端API接口
      token_type: "Bearer",
      user_info: { // 兼容前端API接口
        username: foundUser.username,
        role: foundUser.role,
        permissions: foundUser.role === 'admin' ? ['all'] : ['read']
      },
      // 新格式的响应
      accessToken: accessToken,
      refreshToken: refreshToken,
      user: {
        id: foundUser.id,
        email: foundUser.email,
        username: foundUser.username,
        role: foundUser.role,
        has_face: foundUser.has_face
      }
    });

  } catch (error: any) {
    console.error("登录错误:", error);
    return res.status(500).json({ 
      success: false, 
      message: "服务器内部错误" 
    });
  }
});

// 安全登录接口 - 支持加密传输
router.post("/secure-login", async (req, res) => {
  try {
    const { username, password, encrypted, timestamp, signature } = req.body;
    
    if (!username || !password) {
      return res.status(400).json({ 
        success: false, 
        message: "用户名和密码都是必填项" 
      });
    }

    // 解码密码（如果是加密传输）
    let actualPassword = password;
    if (encrypted) {
      try {
        actualPassword = decodeFrontendPassword(password);
        console.log(`[安全登录] 用户 ${username} 使用加密传输`);
      } catch (error) {
        return res.status(400).json({ 
          success: false, 
          message: "密码解码失败，请重试" 
        });
      }
    }

    // 验证时间戳（防重放攻击）
    if (timestamp) {
      const now = Date.now();
      const timeDiff = Math.abs(now - timestamp);
      if (timeDiff > 5 * 60 * 1000) { // 5分钟有效期
        return res.status(400).json({ 
          success: false, 
          message: "请求已过期，请重新登录" 
        });
      }
    }

    // 查找用户
    let foundUser = null;
    for (const user of userDb.values()) {
      if (user.username === username) {
        foundUser = user;
        break;
      }
    }

    if (!foundUser) {
      return res.status(400).json({ 
        success: false, 
        message: "用户名或密码错误" 
      });
    }

    // 验证密码 - 支持新的bcrypt和旧的SHA256
    let passwordValid = false;
    
    if (isLegacyHash(foundUser.password)) {
      // 旧的SHA256哈希，使用同步验证
      passwordValid = legacyHashPassword(actualPassword) === foundUser.password;
      
      // 如果验证成功，升级到bcrypt哈希
      if (passwordValid) {
        console.log(`[密码升级] 为用户 ${foundUser.username} 升级密码哈希到bcrypt`);
        foundUser.password = await hashPassword(actualPassword);
        userDb.set(foundUser.id, foundUser);
      }
    } else {
      // 新的bcrypt哈希，使用异步验证
      passwordValid = await verifyPassword(actualPassword, foundUser.password);
    }
    
    if (!passwordValid) {
      return res.status(400).json({ 
        success: false, 
        message: "用户名或密码错误" 
      });
    }

    console.log(`[安全登录] 用户: ${foundUser.username} (${foundUser.email}) - 角色: ${foundUser.role}`);

    // 生成JWT双 token
    const accessToken = generateAccessToken(foundUser.id, foundUser.role)
    const refreshToken = generateRefreshToken(foundUser.id)

    return res.json({
      success: true,
      access_token: accessToken, // 兼容前端API接口
      token_type: "Bearer",
      user_info: { // 兼容前端API接口
        username: foundUser.username,
        role: foundUser.role,
        permissions: foundUser.role === 'admin' ? ['all'] : ['read']
      },
      // 新格式的响应
      accessToken: accessToken,
      refreshToken: refreshToken,
      user: {
        id: foundUser.id,
        email: foundUser.email,
        username: foundUser.username,
        role: foundUser.role,
        has_face: foundUser.has_face
      }
    });

  } catch (error: any) {
    console.error("安全登录错误:", error);
    return res.status(500).json({ 
      success: false, 
      message: "服务器内部错误" 
    });
  }
});

// 刷新 token
router.post("/refresh-token", (req, res) => {
  try {
    const { refreshToken } = req.body;
    
    if (!refreshToken) {
      return res.status(400).json({ 
        success: false, 
        message: "缺少 refresh token" 
      });
    }

    const validation = validateRefreshToken(refreshToken);
    if (!validation.valid) {
      return res.status(401).json({ 
        success: false, 
        message: "无效或过期的 refresh token" 
      });
    }

    const userId = validation.userId as string;
    let foundUser = null;
    for (const user of userDb.values()) {
      if (user.id === userId) {
        foundUser = user;
        break;
      }
    }

    if (!foundUser) {
      return res.status(404).json({ 
        success: false, 
        message: "用户不存在" 
      });
    }

    // 生成新的 access token
    const newAccessToken = generateAccessToken(userId, foundUser.role);
    console.log(`[Token刷新] 用户: ${foundUser.username} 获取了新的 access token`);

    return res.json({
      success: true,
      accessToken: newAccessToken
    });

  } catch (error: any) {
    console.error("刷新 token 错误:", error);
    return res.status(500).json({ 
      success: false, 
      message: "服务器内部错误" 
    });
  }
});

// 用户修改密码
router.post("/change-password", async (req, res) => {
  try {
    const { username, oldPassword, newPassword } = req.body;
    
    if (!username || !oldPassword || !newPassword) {
      return res.status(400).json({ 
        success: false, 
        message: "用户名、旧密码和新密码都是必填项" 
      });
    }

    // 查找用户
    let foundUser = null;
    for (const user of userDb.values()) {
      if (user.username === username) {
        foundUser = user;
        break;
      }
    }

    if (!foundUser) {
      return res.status(400).json({ 
        success: false, 
        message: "用户不存在" 
      });
    }

    // 解码密码（如果是加密传输）
    let actualOldPassword = oldPassword;
    let actualNewPassword = newPassword;
    
    if (req.body.encrypted) {
      try {
        actualOldPassword = decodeFrontendPassword(oldPassword);
        actualNewPassword = decodeFrontendPassword(newPassword);
      } catch (error) {
        return res.status(400).json({ 
          success: false, 
          message: "密码解码失败，请重试" 
        });
      }
    }

    // 验证旧密码 - 支持新的bcrypt和旧的SHA256
    let oldPasswordValid = false;
    
    if (isLegacyHash(foundUser.password)) {
      // 旧的SHA256哈希，使用同步验证
      oldPasswordValid = legacyHashPassword(actualOldPassword) === foundUser.password;
    } else {
      // 新的bcrypt哈希，使用异步验证
      oldPasswordValid = await verifyPassword(actualOldPassword, foundUser.password);
    }
    
    if (!oldPasswordValid) {
      return res.status(400).json({ 
        success: false, 
        message: "旧密码错误" 
      });
    }

    // 新密码强度验证
    if (actualNewPassword.length < 6) {
      return res.status(400).json({ 
        success: false, 
        message: "新密码长度至少为6个字符" 
      });
    }

    // 更新密码 - 使用bcrypt哈希
    foundUser.password = await hashPassword(actualNewPassword);
    userDb.set(foundUser.id, foundUser);

    console.log(`[密码修改] 用户: ${foundUser.username} 成功修改密码`);

    return res.json({
      success: true,
      message: "密码修改成功"
    });
  } catch (error: any) {
    console.error("修改密码错误:", error);
    return res.status(500).json({ 
      success: false, 
      message: "服务器内部错误" 
    });
  }
});

// 测试接口 - 查看用户数据库状态
router.get("/debug/users", (_req, res) => {
  const users = Array.from(userDb.values()).map(user => ({
    id: user.id,
    username: user.username,
    email: user.email,
    role: user.role,
    has_face: user.has_face,
    created_at: user.created_at
  }));
  
  res.json({
    total_users: userDb.size,
    users: users
  });
});

// 简化的登录测试接口
router.post("/test-login", async (req, res) => {
  try {
    const { username, password } = req.body;
    
    console.log(`[测试登录] 用户名: ${username}, 密码: ${password}`);
    console.log(`[测试登录] 用户数据库大小: ${userDb.size}`);
    console.log(`[测试登录] 所有用户:`, Array.from(userDb.values()).map(u => u.username));
    
    // 查找用户
    let foundUser = null;
    for (const user of userDb.values()) {
      if (user.username === username) {
        foundUser = user;
        break;
      }
    }
    
    console.log(`[测试登录] 找到用户:`, foundUser ? foundUser.username : '未找到');
    
    if (!foundUser) {
      return res.json({
        success: false,
        message: "用户不存在",
        debug: {
          username_searched: username,
          available_users: Array.from(userDb.values()).map(u => u.username)
        }
      });
    }
    
    // 简单密码验证（明文对比，仅用于测试）
    const passwordMatch = foundUser.password === password || await verifyPassword(password, foundUser.password);
    
    console.log(`[测试登录] 密码匹配:`, passwordMatch);
    
    return res.json({
      success: passwordMatch,
      message: passwordMatch ? "登录成功" : "密码错误",
      user: passwordMatch ? {
        id: foundUser.id,
        username: foundUser.username,
        email: foundUser.email,
        role: foundUser.role
      } : null
    });
    
  } catch (error: any) {
    console.error('[测试登录] 错误:', error);
    return res.status(500).json({
      success: false,
      message: "服务器错误",
      error: error.message
    });
  }
});

router.post("/logout", (_req, res) => res.json({ ok: true }));
router.get("/me", (_req, res) => res.json({ user: { id: "u1", role: "manager" } }));

// 导出用户数据库和 refresh token 数据库供其他模块使用（包括MongoDB同步）
export { userDb, refreshTokenDb };

export default router;
